package com.ehotting.mqbd.zw.netty.aop;

import com.ehotting.edsta.mqbd.api.enums.SysModuleEnum;
import com.ehotting.mqbd.api.MQDBConstants;
import com.ehotting.mqbd.api.enums.DirectionEnum;
import com.ehotting.mqbd.api.enums.SendTypeEnum;
import com.ehotting.mqbd.api.enums.TopicEnum;
import com.ehotting.mqbd.core.manager.SolverInfoManager;
import com.ehotting.mqbd.core.service.MQService;
import com.ehotting.mqbd.core.manager.SolverStateManager;
import com.ehotting.mqbd.core.sync.TcpClientMapHelper;
import com.ehotting.mqbd.zw.api.bean.ZwMQTcpData;
import com.ehotting.mqbd.zw.api.constants.ActionConstants;
import com.ehotting.mqbd.zw.api.domain.netty.ZwCommPacket;
import com.ehotting.mqbd.zw.netty.service.ZwMsgStateHandler;
import io.netty.channel.ChannelHandlerContext;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Aspect
@Component
@Slf4j
public class ZWActionAspect {

    @Autowired
    private MQService mqService;
    @Autowired
    private SolverStateManager solverStateManager;
    @Autowired
    private ZwMsgStateHandler zwMsgStateHandler;
    @Autowired
    private TcpClientMapHelper tcpClientMapHelper;
    @Autowired
    private SolverInfoManager solverInfoManager;


    @Pointcut("execution(* com.ehotting.mqbd.zw.netty.zwAction.*.invoke(..))")
    public void messageAction(){

    }

    @Around(value = "messageAction() && args(ctx,request) ", argNames = "pjp,ctx,request")
    public Object aroundMessageAction(ProceedingJoinPoint pjp, ChannelHandlerContext ctx, ZwCommPacket request) throws Throwable{
        log.info("Start aroundMessageAction.");
        Object response  = pjp.proceed(new Object[]{ctx,request});
        sendToClient(request);
        handleState(ctx,request);
        log.info("Finish aroundMessageAction.");
        return response;
    }

    private void sendToClient(ZwCommPacket request) {
        log.info("Start sendToClient.");
        short cmd = request.getHead().getCmd();
        if (cmd == ActionConstants.Cmd_ClusterInfoQuery.getZwCommandVal()){
            return;
        }

        ZwMQTcpData data = ZwMQTcpData.create(TopicEnum.CONCURRENCY,
                request.getDevice(),
                MQDBConstants.DISPATCHER_HOST,
                request.getFrom(), SysModuleEnum.SIMULATION.getCode(),"");
        data.setDirection(DirectionEnum.RESPONSE.getCode());
        data.setResponse(request);

        if (cmd == ActionConstants.Cmd_FileSend.getZwCommandVal()){
            data.setSendType(new SendTypeEnum[]{SendTypeEnum.REDIS_RESPONSE_BODY});
        }

        mqService.request(data);

        log.info("Finish sendToClient.");
    }

    private void handleState(ChannelHandlerContext ctx, ZwCommPacket request){

        if (request.getHead().getCmd() == ActionConstants.Cmd_JobCanceled.getZwCommandVal()
                || request.getHead().getCmd() == ActionConstants.Cmd_JobCompleted.getZwCommandVal()){

            log.info("Solver[AgentId:{},ip:{}] 更新为空闲状态，去掉和agentId/ip的绑定",request.getFrom(),request.getDevice());

            zwMsgStateHandler.handleDelete(request.getFrom());

            Runnable closeRun = new Runnable() {
                @Override
                public void run() {
                    tcpClientMapHelper.shutdownClientDelay(request.getFrom());
                    solverStateManager.setSolverFree(SysModuleEnum.SIMULATION.getCode(),tcpClientMapHelper.getSolverIp(ctx));
                    solverInfoManager.deleteSolverRefAgentId(request.getFrom());
                }
            };
            Thread t = new Thread(closeRun);
            t.start();
        }

    }



}
